home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2006 June / PCpro_2006_06.ISO / files / freeware / openvip.exe / {app} / conv2.py < prev    next >
Encoding:
Python Source  |  2004-01-06  |  33.5 KB  |  836 lines

  1. #
  2. # This file is part of OpenVIP (http://openvip.sourceforge.net)
  3. #
  4. # Copyright (C) 2002-2003
  5. # Michal Dvorak, Jiri Sedlar, Antonin Slavik, Vaclav Slavik, Jozef Smizansky
  6. #
  7. # This program is licensed under GNU General Public License version 2;
  8. # see file COPYING in the top level directory for details.
  9. #
  10. # Conversion from model.timeline object format to network. Important function
  11. # is data_to_network(...) which returns string with xml represantation of
  12. # network.
  13. #
  14.  
  15.  
  16. import xml.dom.minidom
  17. import model
  18. import string
  19. import conv
  20. import globals
  21. import copy
  22. import math
  23.  
  24. input_class_name = 'Input'
  25. output_class_name ='Output'
  26.  
  27. AUDIO_DATA_FORMAT = 1
  28. VIDEO_DATA_FORMAT = 1
  29. DEFAULT_FPS          = 24
  30.  
  31.  
  32. #same as xml.dom.minidom.Document only writes also doctype information
  33. class myDocument(xml.dom.minidom.Document):
  34.         def writexml(self, writer, indent="", addindent="",
  35.                      newl="", encoding = None):
  36.                 writer.write('<?xml version="1.0" ?>\n')
  37.                 if self.doctype is not None:
  38.                         writer.write("<!DOCTYPE %s PUBLIC\n\t \"%s\"\n\t\"%s\">"\
  39.                                 %(self.doctype.name,self.doctype.publicId,self.doctype.systemId))
  40.                 for node in self.childNodes:
  41.                         node.writexml(writer, indent, addindent, newl) 
  42.                 
  43. #object for creating dom elements
  44. g_dom = None
  45.  
  46.  
  47. #for generating module's ids
  48. class incremental:
  49.         def __init__(self):
  50.                 self.__dict = {}
  51.         
  52.         def get(self,item):
  53.                 if not self.__dict.has_key(item):
  54.                         self.__dict[item] = 0
  55.                 self.__dict[item] = self.__dict[item] + 1
  56.                 return self.__dict[item] - 1
  57.                 
  58.         
  59. inc = None
  60.  
  61.  
  62. def addConnection(m_in,m_out,conn_name,cin_cnt,cout_cnt,node):
  63.         con = g_dom.createElement("connect")
  64.         con.setAttribute("module_in",m_in)
  65.         con.setAttribute("module_out",m_out)
  66.         con.setAttribute("conn_in","%s%d"%(conn_name,cin_cnt))
  67.         con.setAttribute("conn_out","%s%d"% (conn_name,cout_cnt))
  68.         node.appendChild(con)   
  69.         
  70.  
  71. def storeParams(params,node):
  72.         for key, value in params.items():
  73.                 par = g_dom.createElement("param")
  74.                 par.setAttribute("name",key)
  75.                 par.appendChild(g_dom.createTextNode(value))
  76.                 node.appendChild(par)
  77.  
  78. def addLoader(object,node,opened_f):
  79.         if opened_f.has_key(object.src_spec["filename"]):
  80.                 return opened_f[object.src_spec["filename"]]
  81.                         
  82.         el = g_dom.createElement("module")
  83.         id = "loader%d" % inc.get("loader")
  84.         el.setAttribute("id",id)
  85.         el.setAttribute("class",input_class_name)
  86.         if checkTrack(object) == "overlay":
  87.                 tmp = {}
  88.                 tmp["filename"] = object.src_spec["filename"]
  89.                 storeParams(tmp,el)
  90.         else: storeParams(object.src_spec,el)
  91.         node.appendChild(el)
  92.         opened_f[object.src_spec["filename"]] = id
  93.         return id
  94.         
  95.  
  96. def checkTrack(object):
  97.         if object.track[0:2] == 'VA' or object.track[0:2] == 'VB' or object.track[0:2] == 'VFx':
  98.                 return "video"
  99.                 
  100.         if object.track[0:2] == 'AA' or object.track[0:2] == 'AB' or object.track[0:2] == 'VFx':
  101.                 return "audio"
  102.         return "overlay"
  103.  
  104. def addFilters(object,node,lid):
  105.         last = lid
  106.         type = checkTrack(object)
  107.         for filter in object.filters:
  108.                 if not filter.active: continue
  109.                 el = g_dom.createElement("module")
  110.                 id = "filter%d" % inc.get("filter")
  111.                 el.setAttribute("id",id)
  112.                 filtername = filter.params
  113.                 if object.track[0] == "V":
  114.                         el.setAttribute("class","VideoFilter")
  115.                         filtername["videofilter"] = filter.name
  116.                 else:
  117.                         el.setAttribute("class","AudioFilter")
  118.                         filtername["audiofilter"] = filter.name
  119.  
  120.                 storeParams(filtername,el)
  121.                 node.appendChild(el)
  122.                 addConnection(last,id,type,0,0,node)
  123.                 last = id               
  124.                         
  125.         return last
  126.  
  127. def addConcat(tr_name,id_array,node,spec_name):
  128.         if spec_name == "": module_name = "concat"
  129.         else : module_name = spec_name
  130.         id = "%s%d" % (module_name,inc.get(module_name))
  131.         el = g_dom.createElement("module")
  132.         el.setAttribute("id",id)
  133.         el.setAttribute("class","Concat")
  134.         par = g_dom.createElement("param")
  135.         par.setAttribute("name","type")
  136.         if tr_name[0] == 'V':
  137.                 par.appendChild(g_dom.createTextNode("video"))
  138.         if tr_name[0] == 'A':
  139.                 par.appendChild(g_dom.createTextNode("audio"))
  140.         el.appendChild(par)
  141.         
  142.         par = g_dom.createElement("param")
  143.         par.setAttribute("name","count")
  144.         par.appendChild(g_dom.createTextNode("%d"%len(id_array)))
  145.         el.appendChild(par)
  146.         node.appendChild(el)
  147.         return id
  148.  
  149. def addConcatenates(track,node,spec_name):
  150.         c_ids = {}
  151.         for (tr_name,id_array) in track.items():
  152.                 id = addConcat(tr_name,id_array,node,spec_name)
  153.                 c_ids[tr_name] = id
  154.                 conn = 0
  155.                 if tr_name[0] == 'V' :
  156.                         conn_name = "video"
  157.                 if tr_name[0] == 'A' :
  158.                         conn_name = "audio"
  159.  
  160.                 
  161.                 if len(id_array) > 0:
  162.                         for modul in id_array:
  163.                                 addConnection(modul[0],id,conn_name,0,conn,node)
  164.                                 conn = conn + 1
  165.  
  166.         return c_ids
  167.         
  168. def addSubset(track,node,last_id,time_from,time_to):
  169.         if track[0] == 'V':
  170.                 type = "video"
  171.         if track[0] == 'A':
  172.                 type = "audio"
  173.  
  174.         id = "subset%d" % inc.get("subset")
  175.         el = g_dom.createElement("module")
  176.         el.setAttribute("id",id)
  177.         el.setAttribute("class","Subset")
  178.         addParam("type",type,el)
  179.         addParam("pos","%10.10f"%time_from,el)
  180.         addParam("length","%10.10f"%(time_to - time_from),el)        
  181.         node.appendChild(el)
  182.         addConnection(last_id,id,type,0,0,node)
  183.         return id
  184.  
  185. def addResize(object,node,last_filter_id,quality,vf):
  186.         id = "resize%d" % inc.get("resize")
  187.         el = g_dom.createElement("module")
  188.         el.setAttribute("id",id)
  189.         el.setAttribute("class","VideoFilter")
  190.         if quality == "preview":
  191.                 addParam("videofilter","SimpleResize",el)
  192.         if quality == "final":
  193.                 addParam("videofilter","Resize",el)
  194.         addParam("width","%d"%vf.width,el)
  195.         addParam("height","%d"%vf.height,el)
  196.         
  197.         node.appendChild(el)
  198.         if object.track[0] ==  "V":type = "video"
  199.         else: type = "audio"
  200.         addConnection(last_filter_id,id,type,0,0,node)
  201.         return id
  202.  
  203.  
  204.  
  205. def addFPSChanger(object,node,last_filter_id,vf,start,end):
  206.         id = "fps_changer%d" % inc.get("fps_changer")
  207.         el = g_dom.createElement("module")
  208.         el.setAttribute("id",id)
  209.         el.setAttribute("class","FPSChanger")
  210.         o_len = min(object.time_to,end) - max(object.time_from,start)
  211.         addParam("fps","%3.10f"%vf.fps,el)
  212.         node.appendChild(el)
  213.         if object.track[0] ==  "V":type = "video"
  214.         else: type = "audio"
  215.         addConnection(last_filter_id,id,type,0,0,node)
  216.         return id
  217.  
  218.  
  219. def c_f(i1,i2):
  220.         return i1[1] - i2[1]
  221.  
  222. def addParam(name,value,node):
  223.         par = g_dom.createElement("param")
  224.         par.setAttribute("name",name)
  225.         par.appendChild(g_dom.createTextNode(value))
  226.         node.appendChild(par)
  227.         
  228. def c_f2(i1,i2):
  229.         if i1[1] ==  i2[1]: return 0
  230.         if i1[1] >  i2[1]: return 1
  231.         return -1
  232.  
  233.                         
  234. def addOverlays2(obj_on_track,node,fin,def_video,def_audio,quality,tmln_length,\
  235.                         tmln_start,opened_f,obj_fps):
  236.         
  237.         last_audio = fin["AA"]
  238.         last_video = fin["VA"]
  239.         for key, value in obj_on_track.items():
  240.                 if key not in ["VA","VB","AA","AB","VFx","AFx"]:
  241.                         id = "overlay%d" % inc.get("overlay")        
  242.                                         
  243.                         if key[0]=="V":
  244.                                 if def_video == None:continue
  245.                                 type = "video"
  246.                                 if last_video == None:
  247.                                         last_video = addNullGen("V",def_video,def_audio,node,\
  248.                                                         tmln_length)
  249.                                 last = last_video
  250.                                 last_video = id
  251.                         if key[0]=="A":
  252.                                 if def_audio == None:continue
  253.                                 type = "audio"
  254.                                 if last_audio == None:
  255.                                         last_audio = addNullGen("A",def_video,def_audio,node,\
  256.                                                         tmln_length)
  257.                                 last = last_audio
  258.                                 last_audio = id
  259.                         new_input_id = storeTrack(value,key,node,\
  260.                                 def_video,def_audio,quality,tmln_length,\
  261.                                 tmln_start,opened_f,obj_fps,last)
  262.                         
  263.                         el = g_dom.createElement("module")
  264.                         el.setAttribute("id",id)
  265.                         el.setAttribute("class","Overlay")
  266.                         tmp = {}
  267.                         if value[0].src_spec.has_key("static_overlay") and \
  268.                                 value[0].src_spec["static_overlay"] == "true":
  269.                                 tmp["static_overlay"]="1"
  270.                         if value[0].src_spec.has_key("x"):
  271.                                 tmp["x"]=value[0].src_spec["x"]
  272.                         if value[0].src_spec.has_key("y"):
  273.                                 tmp["y"]=value[0].src_spec["y"]
  274.  
  275.                         storeParams(tmp,el)         
  276.                         node.appendChild(el)    
  277.                         addConnection(last ,id,type,0,0,node)
  278.                         addConnection(new_input_id,id,type,0,1,node)
  279.                         
  280.         fin["AA"] = last_audio
  281.         fin["VA"] = last_video                        
  282.         return fin        
  283.  
  284.  
  285. def addSaver(node,fin,out_params):
  286.         if fin["AA"] == None and fin["VA"] == None: return None
  287.         
  288.         el = g_dom.createElement("module")
  289.         if out_params.has_key("filename") and out_params["filename"] != None:
  290.             id = "saver%d" % inc.get("saver")
  291.             el.setAttribute("class",output_class_name)
  292.             storeParams(out_params,el)
  293.         else:
  294.             # Store into memory;
  295.             id = "saver"
  296.             el.setAttribute("class", "openvip.highlevel_api.MemOutput")
  297.         el.setAttribute("id",id)
  298.  
  299.         node.appendChild(el)
  300.         if fin["AA"] != None:addConnection(fin["AA"],id,"audio",0,0,node)
  301.         if fin["VA"] != None:addConnection(fin["VA"],id,"video",0,0,node)
  302.         return id
  303.  
  304. def objcmp(o1,o2):
  305.         if o1.time_from < o2.time_from: return -1
  306.         if o1.time_from == o2.time_from: return 0
  307.         return 1
  308.  
  309. def redist(data,ot,tt):
  310.         for obj in data.objects:
  311.                 if not ot.has_key(obj.track):
  312.                         ot[obj.track] = []                
  313.                 ot[obj.track].append(obj)
  314.         for tr in ot.values(): tr.sort(objcmp)
  315.         for trans in data.transitions:
  316.                 if not tt.has_key(trans.track):
  317.                         tt[trans.track] = []                
  318.                 tt[trans.track].append(trans)
  319.         for tr in tt.values(): tr.sort(objcmp)
  320.         
  321.  
  322.  
  323. def addNullGen(type,def_video,def_audio,node,length):
  324.         id = "nullgen%d" % inc.get("nullgen")
  325.         el = g_dom.createElement("module")
  326.         el.setAttribute("id",id)
  327.         el.setAttribute("class","NullGenerator")
  328.         if type[0] == 'V':
  329.                 addParam("type","video",el)
  330.                 addParam("fps","%f"%def_video.fps,el)
  331.                 addParam("frame_width","%d"%def_video.width,el)
  332.                 addParam("frame_height","%d"%def_video.height,el)
  333.                 addParam("frame_format","%d"%VIDEO_DATA_FORMAT,el)
  334.                 addParam("aspect_ratio","%f"%def_video.aspect_ratio,el)
  335.  
  336.         if type[0] == 'A':
  337.                 addParam("type","audio",el)
  338.                 addParam("samplerate","%d"%def_audio.sample_rate,el)
  339.                 addParam("channels","%d"%def_audio.channels,el)
  340.                 addParam("audio_format","%d"%AUDIO_DATA_FORMAT,el)
  341.         addParam("length","%f"%length,el)
  342.                              
  343.         node.appendChild(el)
  344.         return id
  345.  
  346. def storeTrack(objects,type,node,def_video,def_audio,quality,tmln_length,tmln_start,opened_f,\
  347.                                 obj_fps,input_id_for_overlays):
  348.         last_time = tmln_start
  349.         ids = []
  350.         for object in objects:
  351.                 #if object is completly out of computed interval
  352.                 if object.time_to < tmln_start or object.time_from > tmln_start+tmln_length:
  353.                         continue
  354.                 #if there is a space between objects
  355.                 if object.time_from > last_time:
  356.                         if input_id_for_overlays == None:
  357.                                 ng_id = addNullGen(type,def_video,def_audio,node,\
  358.                                         object.time_from - last_time)
  359.                         else:
  360.                                 ng_id = addSubset(object.track,node,input_id_for_overlays,\
  361.                                         last_time,object.time_from)
  362.                         ids.append(ng_id)
  363.                 
  364.                 last_id = addLoader(object,node,opened_f)
  365.                 
  366.                 #if object is not whole in interval
  367.                 #sub_from,sub_to parameters for Subset
  368.                 sub_from = object.src_from
  369.                 if object.src_to != 0:sub_to =  object.src_to
  370.                 else: sub_to = sub_from + object.time_to - object.time_from
  371.         
  372.                 tmln_to = tmln_start + tmln_length
  373.                 
  374.                 if tmln_start > object.time_from:
  375.                         sub_from = sub_from + tmln_start - object.time_from
  376.                 
  377.                 if tmln_to < object.time_to:
  378.                         sub_to = sub_from + tmln_to - max(object.time_from,tmln_start)
  379.                 
  380.                 if object.src_from != 0 or\
  381.                         object.src_to != 0 or\
  382.                         sub_to - sub_from != object.time_to - object.time_from:
  383.                         last_id = addSubset(object.track,node,last_id,sub_from,sub_to)
  384.                         
  385.                                 
  386.                 last_id = addFilters(object,node,last_id)
  387.                 #video must be resized and reFPSed
  388.                 if object.track[0] == "V":
  389.                         if not obj_fps.has_key(object.id) or\
  390.                                         obj_fps[object.id].height != def_video.height or\
  391.                                         obj_fps[object.id].width != def_video.width:
  392.                                 last_id = addResize(object,node,last_id,quality,def_video)
  393.                         if not obj_fps.has_key(object.id) or\
  394.                                         obj_fps[object.id].fps != def_video.fps:
  395.                                 last_id = addFPSChanger(object,node,last_id,def_video,\
  396.                                         tmln_start,tmln_start+tmln_length)
  397.                         
  398.  
  399.         
  400.                 ids.append(last_id)
  401.                 last_time = min(tmln_start + tmln_length,object.time_to)
  402.         
  403.         #if last object doesn't end at the end of the interval        
  404.         if (last_time < tmln_start + tmln_length) and (len(ids)>0):
  405.                 if input_id_for_overlays == None:
  406.                         ng_id = addNullGen(type,def_video,def_audio,node,\
  407.                                 tmln_start + tmln_length - last_time)
  408.                 else:
  409.                         ng_id = addSubset(object.track,node,input_id_for_overlays,\
  410.                                 last_time,tmln_start + tmln_length)
  411.                 ids.append(ng_id)
  412.         
  413.         if len(ids)>1:
  414.                 conid = addConcat(type,ids,node,"")
  415.                 if type[0] == "V":conn_name = "video"
  416.                 else: conn_name = "audio"
  417.                 n = 0
  418.         
  419.                 for id in ids:
  420.                         addConnection(id,conid,conn_name,0,n,node)
  421.                         n =n + 1
  422.         else: 
  423.                 if len(ids)==1: conid = ids[0]
  424.                 else:conid = None
  425.         return conid
  426.         
  427. def addTrans(trans,node,def_video,def_audio,length):
  428.         id = "trans%d" % inc.get("trans")
  429.         el = g_dom.createElement("module")
  430.         el.setAttribute("id",id)
  431.         add_params = trans.params
  432.         if trans.track[0] == "V":
  433.                 el.setAttribute("class","VideoTransition")
  434.                 add_params["transition"] = trans.name
  435.                 add_params["length"] = str(int(math.ceil(length*def_video.fps)))
  436.         else:
  437.                 el.setAttribute("class","AudioTransition")
  438.                 add_params["transition"] = trans.name
  439.                 add_params["length"] = str(int(math.ceil(length*def_audio.sample_rate)))
  440.         
  441.         storeParams(trans.params,el)
  442.         node.appendChild(el)
  443.         return id
  444.  
  445. #Removes objects which are not in (start,end) interval
  446. #objects which are partialy in the interval are cuted to current length
  447. def cutObjects(objects,start,end):
  448.         to_delete = []
  449.         for o in objects:
  450.                 if o.time_to <= start or o.time_from >= end:
  451.                         to_delete.append(o)
  452.                         continue
  453.                 if o.time_from < start:
  454.                         o.time_from = start
  455.                 if o.time_to > end:
  456.                         o.time_to = end
  457.         for o in to_delete:
  458.                 objects.remove(o)
  459.  
  460. def oot_sort(o1,o2):
  461.         if o1.start < o2.start: return -1
  462.         if o1.start == o2.start: return 0
  463.         return 1
  464.  
  465. def addObjectsToAllTracks(all_tracks,objects,id):
  466.         to_add = []
  467.         to_delete = []
  468.         for o in objects:
  469.                 o_id = id
  470.                 if id == "trans": o_id = o.id
  471.                 oot = objOnTrack(o.time_from,o.time_to,o_id)
  472.                 for o2 in all_tracks:
  473.                         if o2.start < oot.start and o2.end > oot.start and o2.end <= oot.end:
  474.                                 o2.end = oot.start
  475.                         if o2.start >= oot.start and o2.start < oot.end and o2.end > oot.end:
  476.                                 o2.start = oot.end
  477.                         if o2.start < oot.start and o2.end > oot.end:
  478.                                 new_obj = objOnTrack(o2.start,o2.end,o2.id)
  479.                                 o2.end = oot.start
  480.                                 new_obj.start = oot.end
  481.                                 all_tracks.append(new_obj)
  482.                         if o2.start >= oot.start and o2.end <= oot.end:
  483.                                 to_delete.append(o2)
  484.                 to_add.append(oot)
  485.         for o in to_delete:
  486.                 all_tracks.remove(o)
  487.         all_tracks.extend(to_add)
  488.         all_tracks.sort(oot_sort)
  489.         
  490.  
  491. class objOnTrack:
  492.         def __init__(self,s,e,id):
  493.                 self.start = s
  494.                 self.end = e
  495.                 self.id = id
  496.  
  497.         
  498. def fillSpaces(arr,id,start,end):
  499.         last = start
  500.         to_add = []
  501.         for o in arr + [objOnTrack(end,end,None)]:
  502.                 if o.start > last:
  503.                         o2 = objOnTrack(last,o.start,id)
  504.                         to_add.append(o2)
  505.                 last = o.end
  506.         arr.extend(to_add)
  507.         arr.sort(oot_sort)
  508.                 
  509. def chainSame(arr):
  510.         while 1:
  511.                 to_del = []
  512.                 for i in range(len(arr)-1):
  513.                         if arr[i].id == arr[i+1].id:
  514.                                 to_del.append(arr[i])
  515.                                 arr[i+1].start = arr[i].start
  516.                 if len(to_del) == 0:break
  517.                 for o in to_del:arr.remove(o)
  518.         
  519. def addTransitions(AVtype,arr,transitions,node,A_id,B_id,def_video,def_audio,start,end):
  520.         if AVtype[0] == "V":type = "video"
  521.         else: type = "audio"
  522.         
  523.         for o in arr:
  524.                 if o.id != A_id and o.id != B_id:
  525.                         direction = 0
  526.                         for tr in transitions:
  527.                                 if tr.id == o.id:
  528.                                         if hasattr(tr,"direction") and tr.direction=="BA":
  529.                                                 direction = 1
  530.                                         o.id = addTrans(tr,node,def_video,def_audio,\
  531.                                                 o.end-o.start)
  532.                                         break
  533.                         if tr.time_from != start or tr.time_to != end:
  534.                                 s_id = addSubset(tr.track,node,A_id,\
  535.                                         tr.time_from - start,tr.time_to - start)                
  536.                         else:s_id = A_id
  537.                         addConnection(s_id,o.id,type,0,direction,node)
  538.                         if tr.time_from != start or tr.time_to != end:
  539.                                 s_id = addSubset(tr.track,node,B_id,\
  540.                                         tr.time_from - start,tr.time_to - start)
  541.                         else:s_id = B_id
  542.                         addConnection(s_id,o.id,type,0,1-direction,node)
  543.                         
  544.         
  545. def mixTracks2(AVtype,objectsA,objectsB,trans,A_id,B_id,node,\
  546.                 def_video,def_audio,tmln_length,tmln_start):
  547.         
  548.         cutObjects(objectsA,tmln_start,tmln_start+tmln_length)
  549.         cutObjects(objectsB,tmln_start,tmln_start+tmln_length)
  550.         cutObjects(trans,tmln_start,tmln_start+tmln_length)
  551.                 
  552.         all_tracks = []
  553.         addObjectsToAllTracks(all_tracks,objectsA,A_id)
  554.         addObjectsToAllTracks(all_tracks,objectsB,B_id)
  555.         addObjectsToAllTracks(all_tracks,trans,"trans")
  556.                         
  557.         if B_id: fillSpaces(all_tracks,B_id,tmln_start,tmln_start+tmln_length)
  558.         else: fillSpaces(all_tracks,A_id,tmln_start,tmln_start+tmln_length)
  559.  
  560.         chainSame(all_tracks)
  561.         
  562.         addTransitions(AVtype,all_tracks,trans,node,A_id,B_id,def_video,def_audio,\
  563.                 tmln_start,tmln_start+tmln_length)
  564.         
  565.         if len(all_tracks) > 1:
  566.                 conid = addConcat(AVtype,all_tracks,node,"")
  567.                 n = 0
  568.                 if AVtype[0] == "V":type = "video"
  569.                 else: type = "audio"
  570.                 for o in all_tracks:
  571.                         if o.id == A_id or o.id == B_id:
  572.                                 o.id = addSubset(AVtype,node,o.id,o.start - tmln_start,\
  573.                                         o.end - tmln_start)        
  574.                         addConnection(o.id,conid,type,0,n,node)
  575.                         n =n + 1
  576.         else: 
  577.                 if len(all_tracks) == 1:
  578.                         conid = all_tracks[0].id
  579.                 else: conid = None
  580.  
  581.         return conid
  582.         
  583.         
  584.  
  585. def selectImplicitFPS(v_obj,obj_fps):
  586.         all = []
  587.         for o in v_obj:
  588.                 i = globals.get_file_info(o.src_spec["filename"])
  589.                 for v in i.video_streams:
  590.                         all.append(v.fps)
  591.                         obj_fps[o.id] = copy.copy(v)
  592.         if len(all) == 0: return DEFAULT_FPS
  593.         all.sort()
  594.         all.reverse()
  595.         val = all[0]
  596.         ret = val
  597.         max_len = 0
  598.         cur_len = 0
  599.         for cur in all:
  600.                 if cur  == val:cur_len = cur_len + 1
  601.                 else: 
  602.                         if cur_len > max_len:
  603.                                 max_len = cur_len
  604.                                 ret = val
  605.                         val = cur
  606.                         cur_len = 0
  607.         if cur_len > max_len:
  608.                 max_len = cur_len
  609.                 ret = val
  610.         return ret
  611.  
  612. def getSpaces(tr,obj,start,end):
  613.         ret = []
  614.         last = start
  615.         if obj.has_key(tr):
  616.                 for o in obj[tr]:
  617.                         if o.time_from > last:
  618.                                 ret.append((last,o.time_from))
  619.                         last = o.time_to
  620.                 if last < end:ret.append((last,end))
  621.         else:ret.append((start,end))
  622.         return ret
  623.  
  624. def cutTrans(trans,spaces):
  625.         to_add = []
  626.         to_del = []
  627.         for tr in trans:
  628.                 for s in spaces:
  629.                         if s[0] <= tr.time_from and s[1] > tr.time_from and s[1] < tr.time_to:
  630.                                 tr.time_from = s[1]
  631.                         if s[0] < tr.time_to and s[1] >= tr.time_to and s[0] > tr.time_from:
  632.                                 tr.time_to = s[0]
  633.                         if s[0] <= tr.time_from and s[1] >= tr.time_to:
  634.                                 to_del.append(tr)
  635.                         if s[0] > tr.time_from and s[1] < tr.time_to:
  636.                                 tr2 = copy.deepcopy(tr)
  637.                                 tr2.id = tr.id + "string@that$_none%could&use-as|name for transition()in_his timeline:-){I hope}+=wdkljvw"
  638.                                 tr.time_to = s[0]
  639.                                 tr2.time_from = s[1]
  640.                                 to_add.append(tr2)
  641.                                 
  642.         for tr in to_del:
  643.                 trans.remove(tr)
  644.         trans.extend(to_add)
  645.                 
  646.  
  647. def recountTransitions(obj,trans,start,end):
  648.         for tr in ["VFx","AFx"]:
  649.                 if trans.has_key(tr):
  650.                         spaces = getSpaces(tr[0]+"A",obj,start,end)
  651.                         cutTrans(trans[tr],spaces)
  652.                         spaces = getSpaces(tr[0]+"B",obj,start,end)
  653.                         cutTrans(trans[tr],spaces)
  654.                         
  655.  
  656. def extractObjects(data,node,def_video,def_audio,quality,output_params,\
  657.                         tmln_length,tmln_start):
  658.         """Extracts objects, mixs them through transitions, adds overlays and Saver modul"""
  659.         
  660.         obj_on_track = {}
  661.         trans = {}
  662.         redist(data,obj_on_track,trans)
  663.         recountTransitions(obj_on_track,trans,tmln_start,tmln_start+tmln_length)
  664.         
  665.         make_video = make_audio = 1
  666.         if def_audio == None:make_audio = 0
  667.         if def_video == None:make_video = 0
  668.         opened_f = {}
  669.                 
  670.         obj_fps = {}
  671.         if make_video:
  672.                 video_for_fps = []
  673.                 if obj_on_track.has_key("VA"):video_for_fps.extend(obj_on_track["VA"])
  674.                 if obj_on_track.has_key("VB"):video_for_fps.extend(obj_on_track["VB"])
  675.                 impl_fps = selectImplicitFPS(video_for_fps,obj_fps)
  676.                 if def_video.fps == None:def_video.fps = impl_fps
  677.                 if obj_on_track.has_key("VA"):
  678.                         VA_id = storeTrack(obj_on_track["VA"],"VA",node,\
  679.                                 def_video,def_audio,quality,tmln_length,\
  680.                                 tmln_start,opened_f,obj_fps,None)
  681.                 else: VA_id = None
  682.                 if obj_on_track.has_key("VB"):
  683.                         VB_id = storeTrack(obj_on_track["VB"],"VB",node,\
  684.                                 def_video,def_audio,quality,tmln_length,\
  685.                                 tmln_start,opened_f,obj_fps,None)
  686.                 else: VB_id = None
  687.                 if not trans.has_key("VFx"):trans["VFx"] = []
  688.                 if not obj_on_track.has_key("VA"):obj_on_track["VA"] = []
  689.                 if not obj_on_track.has_key("VB"):obj_on_track["VB"] = []
  690.                 video_id =mixTracks2("V",obj_on_track["VA"],obj_on_track["VB"],\
  691.                         trans["VFx"],VA_id,VB_id,node,\
  692.                         def_video,def_audio,tmln_length,tmln_start)
  693.         else: video_id = None
  694.         
  695.         if make_audio:
  696.                 if obj_on_track.has_key("AA"):
  697.                         AA_id = storeTrack(obj_on_track["AA"],"AA",node,def_video,\
  698.                                 def_audio,quality,tmln_length,tmln_start,opened_f,None,None)
  699.                 else: AA_id = None
  700.                 if obj_on_track.has_key("AB"):
  701.                         AB_id = storeTrack(obj_on_track["AB"],"AB",node,def_video,def_audio,\
  702.                                         quality,tmln_length,tmln_start,opened_f,None,None)
  703.                 else: AB_id = None
  704.                 if not trans.has_key("AFx"):trans["AFx"] = []
  705.                 if not obj_on_track.has_key("AA"):obj_on_track["AA"] = []
  706.                 if not obj_on_track.has_key("AB"):obj_on_track["AB"] = []
  707.                 audio_id =mixTracks2("A",obj_on_track["AA"],obj_on_track["AB"],\
  708.                         trans["AFx"],AA_id,AB_id,node,\
  709.                         def_video,def_audio,tmln_length,tmln_start)
  710.         else: audio_id = None
  711.  
  712.  
  713.         fin = {}
  714.         fin["AA"] = audio_id
  715.         fin["VA"] = video_id
  716.  
  717.         fin = addOverlays2(obj_on_track,node,fin,def_video,def_audio,quality,tmln_length,\
  718.                         tmln_start,opened_f,obj_fps)
  719.            
  720.         addSaver(node,fin,output_params)
  721.         
  722. def v_to_dict(v):
  723.         d = {}
  724.         d["width"] = v.width
  725.         d["height"] = v.height
  726.         d["fps"] = v.fps
  727.         d["aspect"] = v.aspect
  728.         return d
  729. def a_to_dict(a):
  730.         d = {}
  731.         d["sample_rate"] = a.sample_rate 
  732.         d["channels"] = a.channels
  733.         return d
  734.         
  735. def getHeighestMostFrequentValue(d,key):
  736.         a = {}
  737.  
  738.         for o in d:
  739.                 if not a.has_key(o[key]):a[o[key]] = 0
  740.                 a[o[key]] = a[o[key]] + 1
  741.  
  742.         max_val = 0
  743.         max_key = 0
  744.         
  745.         for key,val in a.items():
  746.                 if max_val == val and max_key < int(key):
  747.                         max_key = key
  748.                 if max_val < val:
  749.                         max_val = val
  750.                         max_key = key
  751.         return max_key
  752.                 
  753.  
  754. def getDefaultFormat(type,data,tmln_length,tmln_start):
  755.         cutObjects(data.objects,tmln_start,tmln_start+tmln_length)
  756.         
  757.         all_video = []
  758.         all_audio = []
  759.         for o in data.objects:
  760.                 i = globals.get_file_info(o.src_spec["filename"])
  761.                 if type == "video" and o.track[0] == "V":
  762.                         for v in i.video_streams:
  763.                                 all_video.append(v_to_dict(v))
  764.                 if type == "audio" and o.track[0] == "A":
  765.                         for a in i.audio_streams:
  766.                                 all_audio.append(a_to_dict(a))
  767.  
  768.         ret = None                
  769.         if type == "video" and len(all_video) > 0:
  770.                 width = getHeighestMostFrequentValue(all_video,"width")
  771.                 height= getHeighestMostFrequentValue(all_video,"height")
  772.                 fps   = getHeighestMostFrequentValue(all_video,"fps")
  773.                 aspect= getHeighestMostFrequentValue(all_video,"aspect")
  774.                 ret = model.VideoFormat(width,height,fps,aspect)
  775.         if type == "audio" and len(all_audio) > 0:
  776.                 sample_rate = getHeighestMostFrequentValue(all_audio,"sample_rate")
  777.                 channels = getHeighestMostFrequentValue(all_audio,"channels")
  778.                 ret = model.AudioFormat(sample_rate,channels)
  779.         return ret
  780.                                 
  781.         
  782. def getBestAudioFormat(data,tmln_length,tmln_start):
  783.         """Returns best output parameters for audio objects in the part of timeline 
  784.         determined by tmln_length,tmln_start"""
  785.         return getDefaultFormat("audio",data,tmln_length,tmln_start)
  786.  
  787. def getBestVideoFormat(data,tmln_length,tmln_start):
  788.         """Returns best output parameters for video objects in the part of timeline 
  789.         determined by tmln_length,tmln_start"""
  790.         return getDefaultFormat("video",data,tmln_length,tmln_start)
  791.  
  792. #Main function. Returns string with xml network representation
  793. #data - input model object; xmlns,version - xml specifications
  794. #def_video/audio - (video|audio)Format object with default values 
  795. #def_video/audio == 0 means that this video/audio part will be not counted
  796. #quality - preview/final information for Resize module
  797. #f_out - filename for output; tmln_length,tmln_start - timline parameters
  798. def data_to_network(data,xmlns,version,def_video,def_audio,quality,\
  799.                 output_params,tmln_length,tmln_start = 0):
  800.         """Converts model object into xml representation of network (set of
  801.            modules and connections) readable for OpenVIP core. def_video
  802.            def_audio are objects(class videoFormat/audioFormat) with default
  803.            values for video/audio track if some them is None it means, that  
  804.            relevant (vide/audio) tracks will be not computed. quality(preview/final)
  805.            parameter defines what kind of risize module will be used for video objects. 
  806.            In output_params are values for output modul. tmln_length,tmln_start determines
  807.            part of timeilne which will be computed
  808.            Returns string with xml data."""
  809.  
  810.         global g_dom, inc
  811.         g_dom = myDocument()
  812.         inc = incremental()
  813.         
  814.         
  815.         doctype = xml.dom.minidom.DocumentType("network") 
  816.         doctype.publicId = "-//OPENVIP//DTD Network Format V1.0//EN"
  817.         doctype.systemId = "http://openvip.sourceforge.net/dtds/openvip-network.dtd"
  818.         g_dom.doctype = doctype
  819.         
  820.         el = g_dom.createElement("network")
  821.         el.setAttribute("version",version)
  822.         el.setAttribute("xmlns",xmlns)
  823.         import copy
  824.         data2 = copy.deepcopy(data)
  825.         conv.checkInput(data2)
  826.         extractObjects(data2,el,def_video,def_audio,quality,output_params,tmln_length,tmln_start)
  827.         g_dom.appendChild(el)
  828.         
  829. #        s = g_dom.toprettyxml(indent='  ')
  830.         s = g_dom.toxml()
  831.  
  832.         g_dom.unlink()
  833.         
  834.         return s
  835.  
  836.